package IC;

import java.io.*;
import IC.Parser.*;
import IC.AST.*;
import java_cup.runtime.*;

public class Compiler
{	
	
	private static void printUsage() {
		System.out.println("Usage: java IC.Compiler <file.ic> [-L<path_to_libic.sig>] [-print-ast]");
	}
	
	// Parses filenames with LibraryParser or Parser (depends on isLibrary), and returns the root node
	private static ASTNode parseFile(String filename, boolean isLibrary) {
		FileReader txtFile;
		Lexer scanner;
		Symbol root;
		
		try {
			txtFile = new FileReader(filename);
			scanner = new Lexer(txtFile);
			// Instantiate the correct parser according to isLibrary flag
			lr_parser p = isLibrary ? new LibraryParser(scanner) : new Parser(scanner);
			
			root = p.parse();
			System.out.println("Parsed " + filename + " successfully!");
			return (ASTNode)root.value;
		} catch (FileNotFoundException e) {
			System.out.println(e.getMessage());
			return null;
		} catch (IOException e) {
			System.out.println(e.getMessage());
			return null;
		} catch (LexicalError e) {
			System.out.println(e);
			return null;
		} catch (SyntaxError e) {
			System.out.println(e);
			return null;
		} catch (Exception e) {
			System.out.println(e.getMessage());
			return null;
		}
	}
	
	public static void main(String[] args)
	{
		boolean flagPrintAST = false;
		String libFilename = null;
		String icFilename = null;
		ASTNode libRoot = null, icRoot = null;
		
		// Parse all args given to the program, terminating if an unknown parameter is encountered
		String cur;
		for (int i=0; i < args.length; i++) {
			cur = args[i];
			if (!cur.substring(0, 1).equals("-")) {
				if (icFilename != null) {
					System.out.println("Two IC filenames given: " + cur);
					printUsage();
					return;
				}
				icFilename = cur;
			}
			else if (cur.equals("-print-ast")) {
				flagPrintAST = true;
			}
			else if ((cur.length() > 1) && cur.substring(0, 2).equals("-L")) {
				libFilename = cur.substring(2);
				if (libFilename.equals("")) {
					System.out.println("-L flag is on but libic.sig is missing ");
					printUsage();
					return;
				}
			}
			else {
				System.out.println("Wrong argument " + cur);
				printUsage();
				return;
			}
		}
	
		// Terminate the program in cases that that no IC file was given 
		if (icFilename == null) {
			System.out.println("Missing IC Filename.");
			printUsage();
			return;
		}
		
		// Parse the libsig file (if given), and print it if -print-ast in enabled
 		if (libFilename != null) {
 			libRoot = parseFile(libFilename, true);
			if (flagPrintAST == true && libRoot != null) {
				System.out.println((String)libRoot.accept(new PrettyPrinter(libFilename)));
			}
		}
		
 		// Parse the ic file, and print it if -print-ast in enabled
		if (icFilename != null) { 
			icRoot = parseFile(icFilename, false);
			if (flagPrintAST == true && icRoot != null) {
				System.out.println((String)icRoot.accept(new PrettyPrinter(icFilename)));
			}
		}
	}

}
